home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / plug-ins / MapObject / mapobject_image.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-06  |  8.3 KB  |  402 lines

  1. /*********************************************************/
  2. /* Image manipulation routines. Calls mapobject_shade.c  */
  3. /* functions to compute the shading of the image at each */
  4. /* pixel. These routines are used by the functions in    */
  5. /* mapobject_preview.c and mapobject_apply.c             */
  6. /*********************************************************/
  7.  
  8. #include <string.h>
  9.  
  10. #include <sys/types.h>
  11.  
  12. #include <gck/gck.h>
  13.  
  14. #include <libgimp/gimp.h>
  15.  
  16. #include "mapobject_main.h"
  17. #include "mapobject_preview.h"
  18. #include "mapobject_shade.h"
  19. #include "mapobject_ui.h"
  20. #include "mapobject_image.h"
  21.  
  22. GimpDrawable *input_drawable,*output_drawable;
  23. GimpPixelRgn source_region,dest_region;
  24.  
  25. GimpDrawable *box_drawables[6];
  26. GimpPixelRgn box_regions[6];
  27.  
  28. GimpDrawable *cylinder_drawables[2];
  29. GimpPixelRgn cylinder_regions[2];
  30.  
  31. guchar   *preview_rgb_data = NULL;
  32. GdkImage *image = NULL;
  33.  
  34. glong   maxcounter,old_depth,max_depth;
  35. gint    imgtype,width,height,in_channels,out_channels;
  36. GckRGB  background;
  37. gdouble oldtreshold;
  38.  
  39. gint border_x1,border_y1,border_x2,border_y2;
  40.  
  41. /******************/
  42. /* Implementation */
  43. /******************/
  44.  
  45. GckRGB
  46. peek (gint x,
  47.       gint y)
  48. {
  49.   static guchar data[4];
  50.   GckRGB color;
  51.  
  52.   gimp_pixel_rgn_get_pixel(&source_region,data,x,y);
  53.  
  54.   color.r=(gdouble)(data[0])/255.0;
  55.   color.g=(gdouble)(data[1])/255.0;
  56.   color.b=(gdouble)(data[2])/255.0;
  57.  
  58.   if (input_drawable->bpp==4)
  59.     {
  60.       if (in_channels==4)
  61.         color.a=(gdouble)(data[3])/255.0;
  62.       else
  63.         color.a=1.0;
  64.     }
  65.   else
  66.     color.a=1.0;
  67.  
  68.   return(color);
  69. }
  70.  
  71. static GckRGB
  72. peek_box_image (gint image,
  73.         gint x,
  74.         gint y)
  75. {
  76.   static guchar data[4];
  77.   GckRGB color;
  78.  
  79.   gimp_pixel_rgn_get_pixel(&box_regions[image],data,x,y);
  80.  
  81.   color.r=(gdouble)(data[0])/255.0;
  82.   color.g=(gdouble)(data[1])/255.0;
  83.   color.b=(gdouble)(data[2])/255.0;
  84.  
  85.   if (box_drawables[image]->bpp==4)
  86.     {
  87.       if (gimp_drawable_has_alpha(box_drawables[image]->id))
  88.         color.a=(gdouble)(data[3])/255.0;
  89.       else
  90.         color.a=1.0;
  91.     }
  92.   else
  93.     color.a=1.0;
  94.  
  95.   return(color);
  96. }
  97.  
  98. static GckRGB
  99. peek_cylinder_image (gint image,
  100.              gint x,
  101.              gint y)
  102. {
  103.   static guchar data[4];
  104.   GckRGB color;
  105.  
  106.   gimp_pixel_rgn_get_pixel(&cylinder_regions[image],data,x,y);
  107.  
  108.   color.r=(gdouble)(data[0])/255.0;
  109.   color.g=(gdouble)(data[1])/255.0;
  110.   color.b=(gdouble)(data[2])/255.0;
  111.  
  112.   if (cylinder_drawables[image]->bpp==4)
  113.     {
  114.       if (gimp_drawable_has_alpha(cylinder_drawables[image]->id))
  115.         color.a=(gdouble)(data[3])/255.0;
  116.       else
  117.         color.a=1.0;
  118.     }
  119.   else
  120.     color.a=1.0;
  121.  
  122.   return(color);
  123. }
  124.  
  125. void
  126. poke (gint    x,
  127.       gint    y,
  128.       GckRGB *color)
  129. {
  130.   static guchar data[4];
  131.   
  132.   data[0]=(guchar)(color->r*255.0);
  133.   data[1]=(guchar)(color->g*255.0);
  134.   data[2]=(guchar)(color->b*255.0);
  135.   data[3]=(guchar)(color->a*255.0);
  136.   
  137.   gimp_pixel_rgn_set_pixel(&dest_region,data,x,y);
  138. }
  139.  
  140. gint
  141. checkbounds (gint x,
  142.          gint y)
  143. {
  144.   if (x<border_x1 || y<border_y1 || x>=border_x2 || y>=border_y2)
  145.     return(FALSE);
  146.   else
  147.     return(TRUE);
  148. }
  149.  
  150. static gint
  151. checkbounds_box_image (gint image,
  152.                gint x,
  153.                gint y)
  154. {
  155.   gint w,h;
  156.  
  157.   w = box_drawables[image]->width;
  158.   h = box_drawables[image]->height;
  159.  
  160.   if (x<0 || y<0 || x>=w || y>=h)
  161.     return(FALSE);
  162.   else
  163.     return(TRUE);
  164. }
  165.  
  166. static gint
  167. checkbounds_cylinder_image (gint image,
  168.                 gint x,
  169.                 gint y)
  170. {
  171.   gint w,h;
  172.  
  173.   w = cylinder_drawables[image]->width;
  174.   h = cylinder_drawables[image]->height;
  175.  
  176.   if (x<0 || y<0 || x>=w || y>=h)
  177.     return(FALSE);
  178.   else
  179.     return(TRUE);
  180. }
  181.  
  182. GimpVector3
  183. int_to_pos (gint x,
  184.         gint y)
  185. {
  186.   GimpVector3 pos;
  187.  
  188.   pos.x=(gdouble)x/(gdouble)width;
  189.   pos.y=(gdouble)y/(gdouble)height;
  190.   pos.z=0.0;
  191.  
  192.   return(pos);
  193. }
  194.  
  195. void
  196. pos_to_int (gdouble  x,
  197.         gdouble  y,
  198.         gint    *scr_x,
  199.         gint    *scr_y)
  200. {
  201.   *scr_x=(gint)((x*(gdouble)width));
  202.   *scr_y=(gint)((y*(gdouble)height));
  203. }
  204.  
  205. /**********************************************/
  206. /* Compute the image color at pos (u,v) using */
  207. /* Quartics bilinear interpolation stuff.     */
  208. /**********************************************/
  209.  
  210. GckRGB
  211. get_image_color (gdouble  u,
  212.          gdouble  v,
  213.          gint    *inside)
  214. {
  215.   gint   x1, y1, x2, y2;
  216.   GckRGB p[4];
  217.  
  218.   pos_to_int(u,v,&x1,&y1);
  219.  
  220.   if (mapvals.tiled==TRUE)
  221.     {
  222.       *inside=TRUE;
  223.       if (x1 < 0) x1 = (width-1) - (-x1 % width);
  224.       else        x1 = x1 % width;
  225.   
  226.       if (y1 < 0) y1 = (height-1) - (-y1 % height);
  227.       else        y1 = y1 % height;
  228.  
  229.       x2 = (x1 + 1) % width;
  230.       y2 = (y1 + 1) % height;
  231.  
  232.       p[0] = peek(x1, y1);
  233.       p[1] = peek(x2, y1);
  234.       p[2] = peek(x1, y2);
  235.       p[3] = peek(x2, y2);
  236.       return(gck_bilinear_rgba(u * width, v * height, p));
  237.     }
  238.  
  239.   if (checkbounds(x1,y1)==FALSE)
  240.     {
  241.       *inside=FALSE;
  242.       return(background);
  243.     }
  244.  
  245.   x2 = (x1 + 1);
  246.   y2 = (y1 + 1);
  247.  
  248.   if (checkbounds(x2,y2)==FALSE)
  249.    {
  250.      *inside=TRUE;
  251.      return(peek(x1,y1));
  252.    }
  253.  
  254.   *inside=TRUE;
  255.   p[0] = peek(x1, y1);
  256.   p[1] = peek(x2, y1);
  257.   p[2] = peek(x1, y2);
  258.   p[3] = peek(x2, y2);
  259.   return(gck_bilinear_rgba(u * width, v * height, p));
  260. }
  261.  
  262. GckRGB
  263. get_box_image_color (gint    image,
  264.              gdouble u,
  265.              gdouble v)
  266. {
  267.   gint   w,h, x1, y1, x2, y2;
  268.   GckRGB p[4];
  269.  
  270.   w = box_drawables[image]->width;
  271.   h = box_drawables[image]->height;
  272.  
  273.   x1 = (gint)((u*(gdouble)w));
  274.   y1 = (gint)((v*(gdouble)h));
  275.  
  276.   if (checkbounds_box_image(image, x1,y1)==FALSE)
  277.     return(background);
  278.  
  279.   x2 = (x1 + 1);
  280.   y2 = (y1 + 1);
  281.  
  282.   if (checkbounds_box_image(image, x2,y2)==FALSE)
  283.     return(peek_box_image(image, x1,y1));
  284.  
  285.   p[0] = peek_box_image(image, x1, y1);
  286.   p[1] = peek_box_image(image, x2, y1);
  287.   p[2] = peek_box_image(image, x1, y2);
  288.   p[3] = peek_box_image(image, x2, y2);
  289.  
  290.   return(gck_bilinear_rgba(u*w, v*h, p));
  291. }
  292.  
  293. GckRGB
  294. get_cylinder_image_color (gint    image,
  295.               gdouble u,
  296.               gdouble v)
  297. {
  298.   gint   w,h, x1, y1, x2, y2;
  299.   GckRGB p[4];
  300.  
  301.   w = cylinder_drawables[image]->width;
  302.   h = cylinder_drawables[image]->height;
  303.  
  304.   x1 = (gint)((u*(gdouble)w));
  305.   y1 = (gint)((v*(gdouble)h));
  306.  
  307.   if (checkbounds_cylinder_image(image, x1,y1)==FALSE)
  308.     return(background);
  309.  
  310.   x2 = (x1 + 1);
  311.   y2 = (y1 + 1);
  312.  
  313.   if (checkbounds_cylinder_image(image, x2,y2)==FALSE)
  314.     return(peek_cylinder_image(image, x1,y1));
  315.  
  316.   p[0] = peek_cylinder_image(image, x1, y1);
  317.   p[1] = peek_cylinder_image(image, x2, y1);
  318.   p[2] = peek_cylinder_image(image, x1, y2);
  319.   p[3] = peek_cylinder_image(image, x2, y2);
  320.  
  321.   return(gck_bilinear_rgba(u*w, v*h, p));
  322. }
  323.  
  324. /****************************************/
  325. /* Allocate memory for temporary images */
  326. /****************************************/
  327.  
  328. gint
  329. image_setup (GimpDrawable *drawable,
  330.          gint       interactive)
  331. {
  332.   glong  numbytes;
  333.   guchar r,g,b;
  334.  
  335.   /* Set the tile cache size */
  336.   /* ======================= */
  337.  
  338.   gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width() - 1) /
  339.               gimp_tile_width());
  340.  
  341.   /* Get some useful info on the input drawable */
  342.   /* ========================================== */
  343.  
  344.   input_drawable=drawable;
  345.   output_drawable=drawable;
  346.  
  347.   gimp_drawable_mask_bounds (drawable->id,
  348.                  &border_x1, &border_y1, &border_x2, &border_y2);
  349.  
  350.   width=input_drawable->width;
  351.   height=input_drawable->height;
  352.  
  353.   gimp_pixel_rgn_init (&source_region, input_drawable,
  354.                0, 0, width, height, FALSE, FALSE);
  355.  
  356.   maxcounter=(glong)width*(glong)height;
  357.  
  358.   if (mapvals.transparent_background==TRUE)
  359.     gck_rgba_set(&background,0.0,0.0,0.0,0.0);
  360.   else
  361.     {
  362.       gimp_palette_get_background(&r,&g,&b);
  363.       background.r=(gdouble)r/255.0;
  364.       background.g=(gdouble)g/255.0;
  365.       background.b=(gdouble)b/255.0;
  366.       background.a=1.0;
  367.     }
  368.  
  369.   /* Assume at least RGB */
  370.   /* =================== */
  371.  
  372.   in_channels=3;
  373.   if (gimp_drawable_has_alpha(input_drawable->id)==TRUE)
  374.     in_channels++;
  375.  
  376.   if (interactive==TRUE)
  377.     {
  378.       /* Allocate memory for temp. images */
  379.       /* ================================ */
  380.     
  381.       numbytes=PREVIEW_HEIGHT*PREVIEW_WIDTH*3;
  382.     
  383.       image=gdk_image_new(GDK_IMAGE_FASTEST,visinfo->visual,
  384.               PREVIEW_WIDTH,PREVIEW_HEIGHT);
  385.       if (image==NULL)
  386.         return(FALSE);
  387.  
  388.       preview_rgb_data=(guchar *)g_malloc((size_t)numbytes);
  389.       if (preview_rgb_data==NULL)
  390.         return(FALSE);
  391.       memset(preview_rgb_data,0,numbytes);
  392.     
  393.       /* Convert from raw RGB to GdkImage */
  394.       /* ================================ */
  395.  
  396.       gck_rgb_to_gdkimage(visinfo,preview_rgb_data,image,
  397.               PREVIEW_WIDTH,PREVIEW_HEIGHT);
  398.     }
  399.  
  400.   return(TRUE);
  401. }
  402.